#include <stdio.h>
#include <dos.h>
#include "mpx_supt.h"
#include "mrj_supt.h"
#include "R3.H"

pcb* returnHeadR();
void removePCB(char*);
void insertPCB(char*, pcb*);
void cmd_handler();
void load_cmd_handler();

char sys_stack[SYS_STACK_SIZE];
unsigned short ss_save = NULL;
unsigned short sp_save = NULL;
unsigned short new_ss;
unsigned short new_sp;
params *param_p;
context *npc;
pcb* head;   //head of ready queue
char* q;       //pointer of the type of queue
char array[1]; //array holding 'r' or 'b' to represent the queue type

pcb* cop;     //Current operating process

void interrupt dispatch()
{
	if(sp_save == NULL)
	{
		ss_save = _SS;
		sp_save = _SP;
	}
		
		head = returnHeadR();     //Get the head of the ready queue
	
		if((head != NULL) && (head->susp == 0))
		{
			cop = head;              //Set cop to this pcb
			
			dequeueReady();    //Remove the head from the top of the ready queue
			enqueueReady(returnHeadR());
			cop->state = 0;          //Set state to run
			
			new_ss = FP_SEG(cop->stackT);    //sets ss and sp to PCB's stack pointer
			new_sp = FP_OFF(cop->stackT);
			_SS = new_ss;
			_SP = new_sp;
		}
		
		else
		{
			cop = NULL;
			_SS = ss_save;
			_SP = sp_save;
			sp_save = NULL;
			ss_save = NULL;
		}
	
	
	//Return from interupt
}

void interrupt sys_call()
{
	cop->stackT = (unsigned char *)MK_FP(_SS,_SP); 
	_SS = FP_SEG(sys_stack);
	_SP = FP_OFF(sys_stack) + SYS_STACK_SIZE;
	
	array[0] = 'r';
	q = array;
	
	param_p = (params*)(cop->stackT + sizeof(context));  //set pointer to address of actual stack frame
	
	if((param_p->op_code) == IDLE)
	{
		insertPCB(q,cop);
	}
	
	else if((param_p->op_code) == EXIT)
	{
		cop = NULL;
	}
	
	//context_p->AX = result;   //not sure what result is supposed to be yet
	dispatch();
}

void load_cmd_handler()        //This function needs to be cleaned up (iterated), as time permits
{
	pcb *np;
	char* newName;
	char name[10] = {"Comhan\0"};
	int class = 1;
	
	//-----------LOAD COMHAN---------------------

	newName = name;
	
	np = setPCB(newName,127,class);   //create new pcb called np
	np->memSize = 5000;    //Comhan overide stack size
	npc = (context*) np->stackT;
	npc->IP = FP_OFF(&cmd_handler); //test1_R3 is a func name in procs-r3.c
	npc->CS = FP_SEG(&cmd_handler);
	npc->FLAGS = 0x200;
	npc->DS = _DS;
	npc->ES = _ES;
	enqueueReady(np);
	
}
